import { Button, Card, Form, Input, Modal, Select, Space, message } from "antd";
import { getConnectionApi, getShellApi, getToken } from "../utils/client";
import type { AuthInfo, ShellInfo } from "@linksaas-minapp/ssh-proxy-api";
import { useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { ClientInfo } from "../App";
import { DeleteOutlined, FolderOpenOutlined } from "@ant-design/icons";
import { getMinAppInfo, min_app_fs } from "@linksaas-minapp/api";
import type { SshServerInfo } from "@linksaas-minapp/api/extra_info";

export interface ConnectModalProps {
    onCancel: () => void;
    onOk: (clientInfo: ClientInfo) => void;
}

interface AuthInfoWrap {
    wrapId: string;
    authInfo: AuthInfo;
    authMethod: "password" | "privateKey";
}

function ConnectModal(props: ConnectModalProps) {
    const [name, setName] = useState("");
    const [termType, setTermType] = useState("xterm");
    const [authInfoList, setAuthInfoList] = useState<AuthInfoWrap[]>([
        {
            wrapId: uuidv4(),
            authInfo: {
                addr: "",
                username: "",
                password: "",
                privKeyPath: "",
                privKeyPassword: "",
            },
            authMethod: "password",
        },
    ]);

    const connect = async () => {
        const connApi = getConnectionApi();
        let clientId = "";
        let shellInfo: ShellInfo | null = null;
        try {
            clientId = await connApi.connectionOpenPost({
                connectionOpenPostRequest: {
                    token: getToken(),
                    name,
                    authInfoList: authInfoList.map(item => item.authInfo).map(authInfo => {
                        if (!(authInfo.addr?.includes(":"))) {
                            authInfo.addr = (authInfo.addr ?? "") + ":22";
                        }
                        return authInfo;
                    }),
                },
            });
        } catch (e) {
            console.log(e);
            message.error("无法连接SSH服务器");
            return;
        }
        const shellApi = getShellApi();
        try {
            shellInfo = await shellApi.shellOpenPost({
                shellOpenPostRequest: {
                    id: clientId,
                    token: getToken(),
                    termType: termType,
                    width: 80,
                    height: 40,
                },
            });
        } catch (e) {
            console.log(e);
            message.warning("无法打开终端");
        }
        props.onOk({
            id: clientId,
            name: name,
            authList: authInfoList.map(item => `${item.authInfo.username ?? ""}@${item.authInfo.addr ?? ""}`),
            shellList: shellInfo == null ? [] : [shellInfo],
            forwardList: [],
        });
    };

    const checkValid = () => {
        if (name.trim() == "") {
            return false;
        }
        for (const authInfo of authInfoList) {
            if ((authInfo.authInfo.addr ?? "") == "") {
                return false;
            }
            if ((authInfo.authInfo.username ?? "") == "") {
                return false;
            }
            if (authInfo.authMethod == "password") {
                if ((authInfo.authInfo.password ?? "") == "") {
                    return false;
                }
            } else if (authInfo.authMethod == "privateKey") {
                if ((authInfo.authInfo.privKeyPath ?? "") == "") {
                    return false;
                }
            }
        }
        return true;
    }

    const addNewServer = (wrapId: string) => {
        const tmpList: AuthInfoWrap[] = [];
        for (const authInfo of authInfoList) {
            tmpList.push(authInfo);
            if (authInfo.wrapId == wrapId) {
                tmpList.push({
                    wrapId: uuidv4(),
                    authInfo: {
                        addr: "",
                        username: "",
                        password: "",
                        privKeyPath: "",
                        privKeyPassword: "",
                    },
                    authMethod: "password",
                });
            }
        }
        setAuthInfoList(tmpList);
    }

    const choicePath = async (wrapId: string) => {
        const selected = await min_app_fs.openDialog("SSH密钥", false);
        if (selected == null || Array.isArray(selected)) {
            return;
        }
        const tmpList = authInfoList.slice();
        const index = tmpList.findIndex(item => item.wrapId == wrapId);
        if (index != -1) {
            tmpList[index].authInfo.privKeyPath = selected as string;
            setAuthInfoList(tmpList);
        }
    }

    useEffect(() => {
        const minAppInfo = getMinAppInfo();
        if (minAppInfo == undefined) {
            return;
        }
        setName(minAppInfo.extraInfoName ?? "");
        if (minAppInfo.extraInfo != undefined && minAppInfo.extraInfo.length > 0) {
            const serverInfo = JSON.parse(minAppInfo.extraInfo) as SshServerInfo;
            setAuthInfoList([
                {
                    wrapId: uuidv4(),
                    authInfo: {
                        addr: serverInfo.addr ?? "",
                        username: serverInfo.username ?? "",
                        password: serverInfo.password ?? "",
                        privKeyPath: serverInfo.privKeyPath ?? "",
                        privKeyPassword: serverInfo.privKeyPassword ?? "",
                    },
                    authMethod: (serverInfo.usePrivKey ?? false) == false ? "password" : "privateKey",
                },
            ]);
        }
    }, []);

    return (
        <Modal open title="连接SSH服务器" bodyStyle={{ maxHeight: "calc(100vh - 300px)", overflowY: "auto", paddingRight: "20px" }}
            okText="连接" okButtonProps={{ disabled: !checkValid() }}
            onCancel={e => {
                e.stopPropagation();
                e.preventDefault();
                props.onCancel();
            }}
            onOk={e => {
                e.stopPropagation();
                e.preventDefault();
                connect();
            }}>
            <Form labelCol={{ span: 4 }}>
                <Form.Item label="连接名称">
                    <Input value={name} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setName(e.target.value);
                    }} />
                </Form.Item>
                <Form.Item label="终端类型">
                    <Select options={[
                        {
                            label: "xterm",
                            value: "xterm",
                        },
                        {
                            label: "xterm-r6",
                            value: "xterm-r6",
                        },
                        {
                            label: "xterm-256color",
                            value: "xterm-256color",
                        },
                        {
                            label: "vt100",
                            value: "vt100",
                        },
                        {
                            label: "vt220",
                            value: "vt220",
                        },
                        {
                            label: "vt400",
                            value: "vt400",
                        },
                        {
                            label: "vt900",
                            value: "vt900",
                        },
                    ]} value={termType} onChange={value => setTermType(value)} />
                </Form.Item>
            </Form>
            {authInfoList.map((authInfo, authIndex) => (
                <Card key={authInfo.wrapId} style={{ border: "none" }} bodyStyle={{ padding: "10px 0px" }}
                    title={
                        <Space>
                            <span>{authIndex < authInfoList.length - 1 ? `跳板机 ${authIndex + 1}` : "服务器"}</span>
                            <Button type="link" danger disabled={authInfoList.length <= 1} onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                const tmpList = authInfoList.filter(item => item.wrapId != authInfo.wrapId);
                                setAuthInfoList(tmpList);
                            }}><DeleteOutlined /></Button>
                        </Space>
                    }
                    extra={
                        <Button type="link" onClick={e => {
                            e.stopPropagation();
                            e.preventDefault();
                            addNewServer(authInfo.wrapId);
                        }}>增加服务器</Button>
                    }>
                    <Form labelCol={{ span: 4 }}>
                        <Form.Item label="连接地址">
                            <Input value={authInfo.authInfo.addr} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                const tmpList = authInfoList.slice();
                                const index = tmpList.findIndex(item => item.wrapId == authInfo.wrapId);
                                if (index != -1) {
                                    tmpList[index].authInfo.addr = e.target.value;
                                    setAuthInfoList(tmpList);
                                }
                            }} />
                        </Form.Item>
                        <Form.Item label="用户名">
                            <Input value={authInfo.authInfo.username} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                const tmpList = authInfoList.slice();
                                const index = tmpList.findIndex(item => item.wrapId == authInfo.wrapId);
                                if (index != -1) {
                                    tmpList[index].authInfo.username = e.target.value;
                                    setAuthInfoList(tmpList);
                                }
                            }} />
                        </Form.Item>
                        <Form.Item label="验证方式">
                            <Select value={authInfo.authMethod} onChange={value => {
                                const tmpList = authInfoList.slice();
                                const index = tmpList.findIndex(item => item.wrapId == authInfo.wrapId);
                                if (index != -1) {
                                    tmpList[index].authMethod = value;
                                    setAuthInfoList(tmpList);
                                }
                            }}>
                                <Select.Option value="password">密码</Select.Option>
                                <Select.Option value="privateKey">密钥</Select.Option>
                            </Select>
                        </Form.Item>
                        {authInfo.authMethod == "password" && (
                            <Form.Item label="密码">
                                <Input.Password value={authInfo.authInfo.password} onChange={e => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                    const tmpList = authInfoList.slice();
                                    const index = tmpList.findIndex(item => item.wrapId == authInfo.wrapId);
                                    if (index != -1) {
                                        tmpList[index].authInfo.password = e.target.value;
                                        setAuthInfoList(tmpList);
                                    }
                                }} />
                            </Form.Item>
                        )}
                        {authInfo.authMethod == "privateKey" && (
                            <>
                                <Form.Item label="密钥路径">
                                    <Input addonAfter={
                                        <Button type="text" style={{ padding: "0px 0px", height: "20px" }} onClick={e => {
                                            e.stopPropagation();
                                            e.preventDefault();
                                            choicePath(authInfo.wrapId);
                                        }}><FolderOpenOutlined /></Button>
                                    } value={authInfo.authInfo.privKeyPath} onChange={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        const tmpList = authInfoList.slice();
                                        const index = tmpList.findIndex(item => item.wrapId == authInfo.wrapId);
                                        if (index != -1) {
                                            tmpList[index].authInfo.privKeyPath = e.target.value;
                                            setAuthInfoList(tmpList);
                                        }
                                    }} />
                                </Form.Item>
                                <Form.Item label="密钥密码">
                                    <Input.Password value={authInfo.authInfo.privKeyPassword} onChange={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        const tmpList = authInfoList.slice();
                                        const index = tmpList.findIndex(item => item.wrapId == authInfo.wrapId);
                                        if (index != -1) {
                                            tmpList[index].authInfo.privKeyPassword = e.target.value;
                                            setAuthInfoList(tmpList);
                                        }
                                    }} />
                                </Form.Item>
                            </>
                        )}
                    </Form>

                </Card>
            ))}
        </Modal>
    );
}

export default ConnectModal;